﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace MishraReader.Windows.Controls
{
    [TemplatePart(Name = "PART_PasswordBox", Type = typeof(PasswordBox))]
    [TemplatePart(Name = "PART_Watermark", Type = typeof(TextBlock))]
    public class WatermarkPasswordBox : Control
    {
        public static readonly DependencyProperty HasPasswordProperty = DependencyProperty.Register("HasPassword", typeof(bool), typeof(WatermarkPasswordBox),
                                                                                                    new FrameworkPropertyMetadata(false,
                                                                                                                                  FrameworkPropertyMetadataOptions
                                                                                                                                      .BindsTwoWayByDefault,
                                                                                                                                  null, null, true));


        /// <summary>
        ///   Password Dependency Property
        /// </summary>
        public static readonly DependencyProperty PasswordProperty =
            DependencyProperty.Register("Password", typeof(string), typeof(WatermarkPasswordBox),
                                        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                                                                      OnPasswordChanged));

        public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(String), typeof(WatermarkPasswordBox),
                                                                                                  new UIPropertyMetadata(String.Empty));

        private PasswordBox _passwordBox;
        private TextBlock _watermark;

        static WatermarkPasswordBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(WatermarkPasswordBox), new FrameworkPropertyMetadata(typeof(WatermarkPasswordBox)));
        }

        /// <summary>
        ///   Ctr
        /// </summary>
        public WatermarkPasswordBox()
        {
            Focusable = false;
        }

        public bool HasPassword
        {
            get { return (bool)GetValue(HasPasswordProperty); }
            set { SetValue(HasPasswordProperty, value); }
        }

        /// <summary>
        ///   Gets or sets the Password property. This dependency property indicates ....
        /// </summary>
        public string Password
        {
            get { return (string)GetValue(PasswordProperty); }
            set { SetValue(PasswordProperty, value); }
        }

        public String Watermark
        {
            get { return (String)GetValue(WatermarkProperty); }
            set { SetValue(WatermarkProperty, value); }
        }

        /// <summary>
        ///   Get all template controls
        /// </summary>
        public override void OnApplyTemplate()
        {
            if (_passwordBox != null)
            {
                _passwordBox.PasswordChanged -= OnPasswordChanged;
                _passwordBox.LostFocus -= _passwordBox_FocusChanged;
                _passwordBox.GotFocus -= _passwordBox_FocusChanged;
            }

            _passwordBox = (PasswordBox)GetTemplateChild("PART_PasswordBox");
            
            _watermark = (TextBlock)GetTemplateChild("PART_Watermark");

            _passwordBox.PasswordChanged += OnPasswordChanged;
            _passwordBox.LostFocus += _passwordBox_FocusChanged;
            _passwordBox.GotFocus += _passwordBox_FocusChanged;

            UpdateWatermark();
            base.OnApplyTemplate();
        }

        /// <summary>
        ///   Provides derived classes an opportunity to handle changes to the Password property.
        /// </summary>
        protected virtual void OnPasswordChanged(string oldPassword, string newPassword)
        {
            if (_passwordBox != null && _passwordBox.Password != newPassword)
                _passwordBox.Password = newPassword;
        }


        /// <summary>
        ///   Update the watermark visibility
        /// </summary>
        private void UpdateWatermark()
        {
            if (_watermark == null)
                return;

            _watermark.Visibility = HasPassword ? Visibility.Collapsed : Visibility.Visible;
        }

        /// <summary>
        ///   Handles the HasPassword changed event.
        /// </summary>
        /// <param name="sender"> the sender </param>
        /// <param name="eventArgs"> the event args </param>
        private void OnPasswordChanged(object sender, RoutedEventArgs eventArgs)
        {
            HasPassword = _passwordBox.SecurePassword.Length != 0;
            Password = _passwordBox.Password;
            UpdateWatermark();
        }

        /// <summary>
        ///   Focus changed
        /// </summary>
        /// <param name="sender"> </param>
        /// <param name="e"> </param>
        private void _passwordBox_FocusChanged(object sender, RoutedEventArgs e)
        {
            UpdateWatermark();
        }

        /// <summary>
        ///   Handles changes to the Password property.
        /// </summary>
        private static void OnPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = (WatermarkPasswordBox)d;
            var oldPassword = (string)e.OldValue;
            var newPassword = target.Password;
            target.OnPasswordChanged(oldPassword, newPassword);
        }
    }
}